﻿#region Using Statements
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

using AdvanceLib.ScriptCore;
using AdvanceLib.ClassExtensions;
using AdvanceLib.Core;
#endregion

namespace AdvanceLib.ScriptCore.DebugCore
{
    public class Debugger : AdvanceLib.ScriptCore.IDebugger
    {
        #region Constructors
        public Debugger()
        {
            this.DebugPasses = new List<IDebugPass>();
        }
        #endregion

        #region Properties
        public List<IDebugPass> DebugPasses { get; set; }
        #endregion

        #region Methods
        public TDebugger GetDebugger<TDebugger>() where TDebugger : IDebugPass
        {
            return (TDebugger)this.DebugPasses.First(debugger => debugger is TDebugger);
        }
        #endregion

        #region IDebugger Member
        public DebugResult Debug(string input)
        {
            DebugResult result = new DebugResult();

            LineParser lineParser = new LineParser();
            lineParser.Parse(input);

            for (int i = 0; i < lineParser.Lines.Count; i++)
            {
                Line line = lineParser.Lines[i];

                if (!line.IsEmpty)
                {
                    foreach (IDebugPass debugPass in this.DebugPasses)
                    {
                        if (debugPass is LinePass)
                        {
                            LinePass lineDebugger = debugPass as LinePass;

                            lineDebugger.CurrentLineIndex = line.Index + 1;
                            lineDebugger.Pass(result, line.Content);
                        }
                    }
                    for (int j = 0; j < line.Parts.Length; j++)
                    {
                        foreach (IDebugPass debugger in this.DebugPasses)
                        {
                            if (debugger is CommandPass)
                            {
                                CommandPass commandDebugger = debugger as CommandPass;

                                commandDebugger.CurrentLine = line.Content;
                                commandDebugger.CurrentLineIndex = line.Index + 1;
                                commandDebugger.CurrentLinePartIndex = j;
                                commandDebugger.Pass(result, line.Parts[j]);
                            }
                        }
                    }
                    foreach (IDebugPass debugPass in this.DebugPasses)
                    {
                        if (debugPass is IFinalPass && debugPass is CommandPass) (debugPass as IFinalPass).FinalPass(result);
                    }
                }
            }
            foreach (IDebugPass debugPass in this.DebugPasses)
            {
                if (debugPass is IFinalPass && debugPass is LinePass) (debugPass as IFinalPass).FinalPass(result);
            }

            return result;
        }
        #endregion
    }
}
